{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a8823702-8e06-48ca-9002-a7363f7d6f5a",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[NbConvertApp] Converting notebook feature_engineering.ipynb to script\n",
      "[NbConvertApp] Writing 3671 bytes to feature_engineering.py\n"
     ]
    }
   ],
   "source": [
    "!jupyter nbconvert --to script feature_engineering.ipynb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be7c448b-0580-446d-b698-e3ae391d7469",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a1d0e5b-77fa-402d-a1a5-42600b80fe50",
   "metadata": {},
   "outputs": [],
   "source": [
    "#平均值特征构造\n",
    "def add_average_features(df):\n",
    "    columns_to_average = [\n",
    "        ('m1_owe_fee', 'm2_owe_fee', 'm3_owe_fee', 'mean_owe_fee'),  # 用户三个月的缴费\n",
    "        ('m1_calling_cnt', 'm2_calling_cnt', 'm3_calling_cnt', 'mean_calling_cnt'),  # 用户三个月的主叫次数\n",
    "        ('m1_comm_days', 'm2_comm_days', 'm3_comm_days', 'mean_comm_days'),  # 用户三个月通信天数\n",
    "        ('m1_hot_app_flow', 'm2_hot_app_flow', 'm3_hot_app_flow', 'mean_hot_app_flow')  # 用户三个月的热门APP使用流量\n",
    "    ]\n",
    "    for col1, col2, col3, new_col in columns_to_average:\n",
    "        df[new_col] = df[[col1, col2, col3]].mean(axis=1)  # 计算每列的三个月平均值\n",
    "    return df\n",
    "\n",
    "#时间相关特征构造\n",
    "def add_time_features(df):\n",
    "    df['enter_month'] = df['innet_months'] % 12  # 用户入网月份\n",
    "    df['age_innet'] = df['age'] - (df['innet_months'] / 12)  # 用户入网时的年龄\n",
    "    return df\n",
    "\n",
    "#通话特征构造\n",
    "def add_call_features(df):\n",
    "    # 近三个月用户主动呼叫通话次数\n",
    "    df['contact_avg_tocall_cnt_m3'] = df['contact_avg_call_cnt_m3'] - df['contact_avg_called_cnt_m3']  \n",
    "     # 被呼叫比率\n",
    "    df['call_rate'] = df['contact_avg_called_cnt_m3'] / (df['contact_avg_call_cnt_m3'] + 1e-9)  \n",
    "    # 主动呼叫比率\n",
    "    df['tocall_rate'] = df['contact_avg_tocall_cnt_m3'] / (df['contact_avg_call_cnt_m3'] + 1e-9)  \n",
    "    # 国内漫游呼叫比率\n",
    "    df['domestic_roam_call_rate'] = df['domestic_roam_call_count_m3'] / (df['contact_avg_call_cnt_m3'] + 1e-9)  \n",
    "    # 宽带相关呼叫次数\n",
    "    df['bw_contact_call_count_m3'] = df['contact_avg_call_cnt_m3'] / (df['bw_contact_count_m3'] + 1e-9) \n",
    "    # 密集区域通话特征（交往圈规模*规模变化率）\n",
    "    df['dense_sphere'] = df['dense_sphere_num'] * df['dense_sphere_rate']  \n",
    "    return df\n",
    "\n",
    "#用户表现特征构造\n",
    "def add_interaction_features(df):\n",
    "     # 用户积分余额的月均值：用户当前的积分余额除以入网月份数\n",
    "    df['avg_curmon_acum_qty'] = df['curmon_acum_qty'] / df['innet_months']  \n",
    "    # 积分余额增长率：当前积分余额与过去6个月积分余额的平均值的变化率\n",
    "    df['acum_rate'] = (df['curmon_acum_qty'] - df['acum_all_total_6m_mean']) / (df['acum_all_total_6m_mean'] + 1e-9)  \n",
    "    # 近三个月的缴费保持情况： 增加的缴费月数 - 减少的缴费月数\n",
    "    df['pay_fee_keep_3m'] = 3 - df['pay_fee_add_3m'] - df['pay_fee_dec_3m']  \n",
    "    # 家庭宽带与虚拟专网（VPMN）标识的交互特征：反映用户同时订购家庭宽带和虚拟专网服务的情况\n",
    "    df['family_vpmn_interaction'] = df['family_brodbd_flag'] * df['vpmn_flag'] \n",
    "    # 积分余额的月均值：当前的积分余额除以用户的入网时长\n",
    "    df['avg_acum_qty'] = df['curmon_acum_qty'] / (df['innet_months'] + 1e-9)\n",
    "    # 用户星级月平均值：用户的星级评分除以入网月份数，反映长期星级表现\n",
    "    df['avg_star_level'] = df['star_level'] / (df['innet_months'] + 1e-9)\n",
    "    return df\n",
    "\n",
    "#变化率特征构造\n",
    "def add_growth_rate_features(df):\n",
    "    for metric in ['hot_app_flow', 'comm_days', 'calling_cnt', 'owe_fee']:#热门APP使用流量、通信天数、主叫次数、缴费金额\n",
    "        for i,j,k in [[1,1,2],[2,1,3],[3,2,3]]:\n",
    "            df[f'{metric}_growth_rate{i}'] = (df[f'm{k}_{metric}'] - df[f'm{j}_{metric}']) / (df[f'm{j}_{metric}'] + 1e-9)  #变化率\n",
    "            df[f'{metric}_change{i}'] = df[f'm{k}_{metric}'] - df[f'm{j}_{metric}']  #变化量\n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b3ec6811-9f90-4bf8-bebc-853f3ce9eda9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def preprocess_data(data_path):\n",
    "    data = pd.read_csv(data_path)\n",
    "\n",
    "    data = add_average_features(data)\n",
    "    data = add_time_features(data)\n",
    "    data = add_call_features(data)\n",
    "    data = add_interaction_features(data)\n",
    "    data = add_growth_rate_features(data)\n",
    "\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "30140d82-87bd-4f02-ac58-6a805b2748c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "if __name__ == \"__main__\":\n",
    "    data_path = '../init_data/raw/测试集A/train.csv'\n",
    "    train_data = preprocess_data(data_path)\n",
    "    print(\"Train data shape:\", train_data.shape)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
